package com.zhuoyue.biz.core.api.service.impl.device;

import com.zhuoyue.biz.core.api.domain.DeviceAndGatewayDO;
import com.zhuoyue.biz.core.api.dto.req.ControlReq;
import com.zhuoyue.biz.core.api.service.GatewayRedisService;
import com.zhuoyue.common.constant.ControlType;
import com.zhuoyue.common.utils.CmdUtils;
import com.zhuoyue.common.utils.Time;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author zhanghui
 * @Date: 2021/06/15/11:03
 * @Description: 灯带控制器拼帧
 */

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SwitchControllerCommon {
    private final RedisTemplate redisTemplate;
    private final GatewayRedisService gatewayRedisService;
    private static final String DELAY_TIME = "delayTime";
    /**
     * 是否为群组
     */
    private static boolean isGroup = false;

    public String switchControllerDeal(DeviceAndGatewayDO deviceAndGatewayDO, ControlReq controlReq) {
        String cmd = control(deviceAndGatewayDO, controlReq);
        return cmd;
    }

    private String control(DeviceAndGatewayDO deviceAndGatewayDO, ControlReq controlReq) {
        String controlType = controlReq.getControlType();
        String gatewayMac = deviceAndGatewayDO.getGatewayMac();
        String deviceMac = deviceAndGatewayDO.getZigbeeMac();
        //延时时间，单位秒
        int delayTime = 0;
        int duration = 0;

        Map<String, Object> actions = controlReq.getActions();

        //获取延时时间
        if (actions != null && actions.containsKey(DELAY_TIME)) {
            delayTime = Integer.parseInt(actions.get(DELAY_TIME).toString());
        }

        String cmd = "";
        switch (controlType) {
            //打开
            case ControlType.TURN_ON_REQUEST:
                cmd = openControlCmd(gatewayMac, deviceMac, duration, delayTime);
                break;
            //关闭
            case ControlType.TURN_OFF_REQUEST:
                cmd = closeControlCmd(gatewayMac, deviceMac, duration, delayTime);
                break;
            //取消延时
            case ControlType.CANCEL_DELAY_REQUEST:
                cmd = cancelDelayCmd(gatewayMac, deviceMac);
                redisTemplate.delete(deviceAndGatewayDO.getZigbeeMac() + "_delayTime");
                break;
            default:
                break;
        }

        if (ControlType.TURN_OFF_REQUEST.equals(controlType)) {
            //若是延时关，则将关闭时间点的时间戳存到redis
            if (delayTime > 0) {
                long closeTime = Time.toLongMilli(LocalDateTime.now()) + delayTime * 1000L;
                redisTemplate.opsForValue().set(deviceAndGatewayDO.getZigbeeMac() + "_delayTime", closeTime, delayTime, TimeUnit.SECONDS);
            } else {
                //若只是关闭，则需要发送取消延时的命令，防止之前设置过延时关闭而之后触发
                Boolean delete = redisTemplate.delete(deviceAndGatewayDO.getZigbeeMac() + "_delayTime");
                //若有数据删除，则发送取消延时
                if (delete) {
                    String cancelDelayCmd = cancelDelayCmd(gatewayMac, deviceMac);
                    gatewayRedisService.writeDataToGateway(gatewayMac, cancelDelayCmd);
                    try {
                        Thread.sleep(200);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }
            }
        }
        return cmd;
    }

    private static String openControlCmd(String gatewayMac, String deviceMac, Integer duration, Integer delayTime) {
        String durationStr = CmdUtils.getHighPositionReplacement(CmdUtils.getHexString(duration));
        String delayTimeStr = CmdUtils.getHighPositionReplacement(CmdUtils.getHexString(delayTime));

        String cmd10To15 = "1F000000" + "01" + durationStr + delayTimeStr + "00000000" + "00000000";

        return commonCmdDeal(cmd10To15, gatewayMac, deviceMac);
    }

    private static String closeControlCmd(String gatewayMac, String deviceMac, Integer duration, Integer delayTime) {
        String durationStr = CmdUtils.getHighPositionReplacement(CmdUtils.getHexString(duration));
        String delayTimeStr = CmdUtils.getHighPositionReplacement(CmdUtils.getHexString(delayTime));

        String cmd10To15 = "1F000000" + "02" + durationStr + delayTimeStr + "00000000" + "00000000";

        return commonCmdDeal(cmd10To15, gatewayMac, deviceMac);
    }

    private static String cancelDelayCmd(String gatewayMac, String deviceMac) {
        String cmd10To15 = "1F000000" + "0D" + "0000" + "0000" + "00000000" + "00000000";
        return commonCmdDeal(cmd10To15, gatewayMac, deviceMac);
    }

    private static String commonCmdDeal(String cmd10To15, String gatewayMac, String deviceMac) {
        String cmd9 = CmdUtils.getDateLength(cmd10To15);
        String cmd4 = "";

        if (isGroup) {
            cmd4 = "02";
        } else {
            cmd4 = "01";
        }

        String cmd3To15 = "02" + cmd4 + gatewayMac + deviceMac + "0FAA" + "FF" + cmd9 + cmd10To15;
        String cmd2 = CmdUtils.getDateLength(cmd3To15);
        String cmd16 = CmdUtils.getCmdBodySum(cmd3To15);
        String fullCmd = "2A" + cmd2 + cmd3To15 + cmd16 + "23";
        return fullCmd;
    }
}
